home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / tools / ask / gmoji / source / gmoji.s < prev   
Text File  |  2000-02-16  |  21KB  |  864 lines

  1. *********************************************************************
  2. *        テキスト文字読み取りツール
  3. *            GMOJI
  4. *        Copyright (C) 1997-98,2000 by AIG-Soft
  5. *********************************************************************
  6.  
  7.     .include    defines.mac
  8.     .include    pspdef.mac
  9.     .include    skey.mac
  10.     .include    ksd.mac
  11.     .include    gmd.mac
  12.     .lall        * マクロを展開して表示する(主にデバッグ用)
  13.  
  14. OCUR        equ    $0000_ffff    * 元々のカーソル形状
  15.             * 0ライン目から$ff
  16. FCUR        equ    $0008_ffff    * 普通モードカーソル
  17.             * 8ライン目から$ff
  18. HCUR        equ    $000c_cccc    * 半角モードカーソル
  19.             * 12ライン目から$cc
  20.  
  21. *********************************************************************
  22. *    常駐ルーチン
  23. *********************************************************************
  24. * 年号をわざわざテキストでなしにバイナリー化しているのは、テキストのみより
  25. * 誤った一致をしにくいから
  26.  
  27.     .text
  28.     .even
  29. KEEP_START:
  30.     * 常駐確認用識別子
  31. id:    .dc.b    'GetMoji V1.4',20,$00,'AIG-Soft',0
  32.  
  33. *********************************************************************
  34. * ワーク1
  35. *********************************************************************
  36.  
  37.     .even
  38.     * 外部プログラム定義 : Opt.1+TABで起動
  39. ExtFunc:    .dc.b    .low.(SKtab>>8)    * 起動キー(スキャンコード)
  40.         .dc.b    SKopt1    * シフト状態
  41.         .dc.l    GMOJI    * 起動アドレス
  42.         .dc.l    0    * 予約
  43.  
  44. OutFile:    * 全画面一気ファイル書き出し時のファイル名
  45.     .dc.b    'Gamen.gmd',0    * 5+1+3+1バイト
  46. OutFileEnd:
  47.     .ds.b    96-(5+1+3+1)    * 全体で96バイト確保
  48. *    将来のファイル名変更機能追加のための布石
  49.     .even
  50.  
  51. AdGMDAPI:    .dc.l    0    * GMDのAPIアドレス
  52. AdKSDAPI:    .dc.l    0    * KSDのAPIアドレス
  53.  
  54. mode        .dc.b    0    * 読みとりモード     0=普通 , $ff=半角化(for ASK)
  55. cur        .dc.b    0    * 初期のカーソル状態
  56.  
  57. CurPTRN:    * 半角モード時のカーソル形状
  58.         .dc.b    $00,$00,$00,$00,$00,$00,$00,$00
  59.         .dc.b    $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
  60.  
  61.     .even
  62.  
  63. *********************************************************************
  64. * 本来外部にあるべきルーチン
  65. *********************************************************************
  66.  
  67. GMDAPI0    macro no
  68.     moveq.l    #no,d0        * コマンドセット
  69.     bsr    GMDCallAPI0    * GMD API呼びだし
  70.     endm
  71.  
  72. KSDAPI0    macro no
  73.     moveq.l    #no,d0        * コマンドセット
  74.     bsr    KSDCallAPI0    * KSD API呼びだし
  75.     endm
  76.  
  77.  
  78. KSDCallAPI0:            * API呼びだし
  79. * d0.b=コマンド
  80.     move.l    AdKSDAPI(pc),-(sp)
  81.     rts            * 飛び先からrtsする
  82.  
  83. GMDCallAPI0:            * API呼びだし
  84. * d0.b=コマンド
  85.     move.l    AdGMDAPI(pc),-(sp)
  86.     rts            * 飛び先からrtsする
  87.  
  88. *********************************************************************
  89.  
  90. ModeSet    macro
  91. * 初期設定
  92.     * GMD設定(使用直前に設定する)
  93.     lea    Writer(pc),a2
  94.     GMDAPI0    GMD_SetWriter    * Writer設定
  95.     move.l    d0,Wt
  96.     sub.l    a2,a2        * デフォルト設定
  97.     GMDAPI0    GMD_SetGroup    * Group設定
  98.     move.l    d0,Gp
  99.     move.l    CSRX.w,xy0    * 元のカーソル位置保存
  100.     * マウス処理
  101.     IOCS    _MS_STAT    * マウスカーソル表示モード保存
  102.     move.w    d0,msc        * 0=off , -1=on
  103.     IOCS    _MS_CUROF    * マウスカーソルは消す
  104.     * カーソル処理
  105.     move.b    CSRSWITCH.w,cur    * カーソル表示状態保存
  106.     IOCS    _OS_CURON    * カーソル表示
  107.     moveq.l    #1,d1
  108.     IOCS    _B_CONMOD    * カーソル点滅停止(IOCS.X)
  109.     *
  110.     * ASK判定(V1.21)
  111.     * ASKがない時は一部処理を無効にするため(ASKの内部ルーチンを使うから)
  112.     st    mode        * OFFで$FFにする
  113.     pea    50.w
  114.     DOS    _KNJCTRL    * version check
  115.     addq.l    #4,sp
  116.     tst.l    d0        * ASK none = -1
  117.     smi    fask        * ASKが無いならfask!=0
  118.     bmi    10f        * ASKがない
  119.     * モード設定 (V1.2でASK自動判別にする)
  120.     * ノーマルASKでfpcallを使って変換ラインのON/OFFを見分ける(Thanks FDSさん)
  121.     pea    8.w
  122.     DOS    _KNJCTRL
  123.     move.l    d0,-(sp)
  124.     pea    7.w
  125.     DOS    _KNJCTRL
  126.     lea    12(sp),sp
  127.     tst.l    d0        * 0ならASKはOFF,2ならON状態
  128.     seq    mode        * OFFで$FFにする
  129. 10:    bsr    MODE_SET    * ここで反転されるので↑で良い
  130.     * V1.12まで
  131.     *clr.b    mode        * 初期は常に普通取り込み
  132.     *bsr    NormalWaku
  133.     *
  134.     IOCS    _ONTIME        * 枠点滅初期時間
  135.     move.l    d0,tm0
  136.     endm
  137.  
  138. ModeReset    macro
  139. * 戻し
  140. local L1,L2
  141.     * カーソルを元に戻す
  142.     tst.b    cur
  143.     bne    L1
  144.     IOCS    _OS_CUROF    * カーソル非表示
  145. L1:    moveq.l    #0,d1
  146.     IOCS    _B_CONMOD    * カーソル点滅(IOCS.X)
  147.     moveq.l    #0,d0        * 枠パターン:消去
  148.     bsr    CurWaku        * V1.12
  149.     * マウスカーソルを元に戻す
  150.     moveq.l    #_MS_CUROF,d0
  151.     tst.w    msc
  152.     beq    L2
  153.     moveq.l    #_MS_CURON,d0
  154. L2:    trap    #15        * IOCS
  155.     * GMDを戻す
  156.     move.l    Wt(pc),d0
  157.     GMDAPI0    GMD_SetWriter    * Writer戻し
  158.     move.l    Gp(pc),d0
  159.     GMDAPI0    GMD_SetGroup    * Group戻し
  160.     endm
  161.  
  162. *---------------------------------------------------
  163.  
  164. GMOJI:
  165. * メインルーチン
  166. * KSDからの起動なのでスーパーバイザーモードで動く
  167.     movem.l    d3-d7/a3-a6,-(sp)    * レジスタ保存
  168.     ModeSet            * APIなどの設定
  169.     *
  170. 1:    move.l    CSRXMAX.w,d5    * テキスト画面の幅-1:xm|ym
  171.     swap    d5
  172.     move.l    CSRX.w,d6    * カーソル位置      : x|y
  173.     swap    d6        * xの方がよく処理されるのでxをlowに置く
  174. 2:    * キー入力
  175.     IOCS    _ONTIME        * 時間
  176.     move.l    d0,d1        * 保存
  177.     sub.l    tm0,d0        * t-tm0
  178.     cmp.l    #17,d0        * 枠点滅(1/6≒17/100sec)
  179.     bls    3f
  180.     bsr    WakuRev        * 枠反転
  181.     move.l    d1,tm0
  182. 3:    KSDAPI0    KSD_B_KEYSNS    * キー入力センス
  183.     tst.w    d0        * 入力有り?
  184.     beq    2b        * No
  185.     * キー入力がある
  186.     KSDAPI0    KSD_B_KEYINP    * キー入力
  187.     move.w    d0,d1        *         -> d1.w
  188.     KSDAPI0    KSD_B_SFTSNS    * シフト状態 -> d0.w
  189.     moveq.l    #0,d7        * 継続の印
  190.     * キー入力別処理へ飛ぶ
  191.     lea    TJTable(pc),a0
  192. @@:    move.l    (a0)+,d2    * jump|code
  193.     beq    2b        * -> end of table : 操作キーでない -> 戻る
  194.     cmp.w    d1,d2        * =code?
  195.     bne    @b        * no
  196.     swap    d2        * d0=jump
  197.     jsr    -4(a0,d2.w)
  198.     * <- ここに戻ってくる(d7.l=0:継続,<>0:終了)
  199.     * カーソル移動
  200.     swap    d6        * y|x -> x|y
  201.     bmi    @f        * d6.l=-1のときはカーソルはすでに移動されているので処理しない
  202.     cmp.l    CSRX.w,d6
  203.     beq    @f        * 移動はない
  204.     * カーソルoffは移動時の瞬間だけにしてカーソルが見えなくなるのを最小限にする
  205.     IOCS    _B_CUROFF    * カーソルを操作するため
  206.     move.l    d6,CSRX.w
  207.     IOCS    _B_CURON    * カーソル戻し
  208. @@:    tst.l    d7        * 終了?
  209.     beq    1b        * No -> 継続
  210.     *
  211.     ModeReset        * 戻し
  212.     movem.l    (sp)+,d3-d7/a3-a6    * レジスタ復帰
  213.     rts
  214.  
  215. *------------------------------------
  216. * d1.w=スキャンコード
  217. * d0.w=シフト状態
  218.  
  219. TJTable:
  220.     * jump先(offset),code
  221.     .dc.w    LT_SPC-$,SKspc
  222.     .dc.w    LT_CR-$,SKcr    * メインキー
  223.     .dc.w    LT_CR-$,SKent    * テンキー
  224.     .dc.w    LT_ESC-$,SKesc
  225.     .dc.w    LT_CLR-$,SKclr
  226.     .dc.w    LT_MODE-$,SKf1
  227.     .dc.w    LT_REVMODE-$,SKf5
  228.     * 以下はカーソル移動キー
  229.     .dc.w    LT_UNDO-$,SKundo
  230.     .dc.w    LT_LEFT-$,SKleft
  231.     .dc.w    LT_UP-$,SKup
  232.     .dc.w    LT_RIGHT-$,SKright
  233.     .dc.w    LT_DOWN-$,SKdown
  234.     .dc.w    LT_TAB-$,SKtab
  235.     .dc.w    LT_DEL-$,SKdel
  236.     .dc.w    LT_HOME-$,SKhome
  237.     .dc.w    0,0        * end of table
  238.  
  239. *------------------------------------
  240.  
  241. SetWakuH:
  242. * 枠の初期状態設定(半角モード用)
  243.     move.l    #$0008_0008,d0    * wx,wy = 8,8
  244.     bra.s    @f
  245. *
  246. SetWaku:
  247. * 枠の初期状態設定(普通モード用)
  248.     move.l    #$0008_0010,d0    * wx,wy = 8,16
  249. @@:    lea    txarg(pc),a1
  250.     move.l    d0,6(a1)    * wx,wy
  251.     *
  252.     moveq.l    #-1,d1
  253.     moveq.l    #-1,d2
  254.     IOCS    _B_CONSOL    * -> d1.h.w=x-offset , d1.l.w=y-offset
  255.     move.w    xy0+2(pc),d0    * y
  256.     lsl.w    #4,d0        * y*16
  257.     add.w    d1,d0        * +y-offset
  258.     move.w    d0,4(a1)
  259.     swap    d1
  260.     move.w    xy0(pc),d0    * x
  261.     lsl.w    #3,d0        * x*8
  262.     add.w    d1,d0        * +x-offset
  263.     move.w    d0,2(a1)
  264.     move.w    #2,(a1)        * text plane2
  265.     rts
  266.  
  267. WakuRev:
  268. * 枠反転
  269. * d0.l 破壊
  270.     lea    txarg(pc),a1
  271.     eor.w    #$ffff,10(a1)    * 枠パターン反転
  272.     IOCS    _TXBOX
  273.     rts
  274. *
  275. Waku:
  276. * 元カーソル位置枠描画
  277. * d0.w <- 枠パターン
  278. * d0.l 破壊
  279.     lea    txarg(pc),a1
  280.     move.w    d0,10(a1)    * 枠パターン
  281.     IOCS    _TXBOX
  282.     rts
  283.  
  284. *------------------------------------
  285. * その他
  286.  
  287. LT_REVMODE:    * 反転文字読みとりモード設定(押す度にモード反転)
  288.     GMDAPI0    GMD_ReadVer    * バージョン読み取り
  289.     cmp.w    #$0104,d0
  290.     bcs    @f        * <V1.4なので無効
  291.     moveq.l    #-1,d1        * 現在のモード読み取り
  292.     GMDAPI0    GMD_RevMode    * d0.l=$00/$FF
  293.     not.b    d0        *    ->$FF/$00
  294.     move.l    d0,d1
  295.     GMDAPI0    GMD_RevMode    * d0.l=$00/$FF
  296. @@:    rts
  297.  
  298. LT_MODE:    * 読みとりモード設定
  299.     * ASKがない時は無効(ASKの内部ルーチンを使うから)
  300.     tst.b    fask
  301.     bne    10f        * ASKがない
  302.     *
  303.     moveq.l    #0,d0        * 枠パターン:消去
  304.     bsr    Waku        * 一旦枠を消す
  305. MODE_SET:
  306.     eor.b    #$ff,mode    * モード反転
  307.     beq    NormalWaku    * on -> off
  308.     * off-> on : 半角モード
  309.     bsr    SetWakuH
  310.     move.w    #$5555,d0    * 枠パターン
  311.     bsr    Waku        * 初期枠
  312.     * V1.1
  313.     moveq.l    #0,d1
  314.     lea    CurPTRN(pc),a1    * カーソル形状
  315.     IOCS    _DEFCHR        * カーソル形状設定
  316. 10:    rts
  317.  
  318. NormalWaku:    * 普通モード
  319.     bsr    SetWaku
  320.     move.w    #$cccc,d0    * 枠パターン
  321. CurWaku:    * カーソル戻して枠設定(V1.12)
  322.     bsr    Waku        * 初期枠
  323.     moveq.l    #-1,d1        * V1.1
  324.     IOCS    _DEFCHR        * カーソル形状戻し
  325.     rts
  326.  
  327. LT_CLR:    * キーバッファークリア
  328.     and.w    #SKsft,d0
  329.     beq    @f        * CLRのみ -> 何もしない
  330.     BEEP
  331.     KSDAPI0    KSD_Clear
  332. @@:    rts
  333.  
  334. *------------------------------------
  335. * 読み取り処理
  336.  
  337. LT_SPC:    * 1文字取得
  338.     moveq.l    #-1,d6        * カーソルはすでに移動されているの印
  339.     move.w    d0,d1
  340.     and.w    #SKctrl,d0
  341.     beq    @f        * ->SPCで1文字読みとり/OPT.1+SPCで全画面読み取り
  342.     * CTRL+SPC:単語一気読みとり
  343.     moveq.l    #-1,d1        * 現在カーソル位置から
  344.     GMDAPI0    GMD_ReadTango    * カーソルも移動する
  345.     tst.l    d0
  346.     beq    err
  347.     rts
  348. *
  349. @@:    and.w    #SKopt1,d1
  350.     bne    ALLGET        * ->全画面書き出し
  351.     * SPC:1文字読み込み
  352.     * 1文字読み込み
  353.     moveq.l    #-1,d1        * 現在カーソル位置から
  354.     GMDAPI0    GMD_Read1    * -> d0.l
  355.     move.l    d0,d1        * 保存
  356.     swap    d1        * d1.w=幅
  357.     GMDAPI0    GMD_MoveCursor    * カーソル移動
  358.     swap    d1        * d1.w=文字
  359.     cmp.w    #NOCHR,d1
  360.     bne    @f
  361. err:    BEEP            * 読み取れなかった
  362.     rts
  363.  
  364. @@:    * 読み取れた
  365.     bsr    Writer0        * 書き込み(d1.w)
  366.     rts
  367. *
  368. *
  369. ALLGET:    * OPT.1+SPC:全画面書き出し
  370.     * ここの処理において、GMDのWriterの変更で書き出ししても良いが、
  371.     * Writerは初期化時に別ルーチンに設定されているので、
  372.     * ここで再設定するのが面倒なのでやめている。
  373.     *
  374.     * ファイルオープン
  375.     * ここの処理はfopen(OutFile,"at+")の処理と同じである。
  376.     * 汎用的に使えるような気がする。
  377.     move.w    #RWOPEN,-(sp)    * 読み書きモード
  378.     pea    OutFile(pc)
  379.     DOS    _OPEN
  380.     addq.w    #6,sp
  381.     tst.l    d0
  382.     bmi    create
  383.     * ファイルがオープン出来た
  384.     move.w    d0,fp        * fp記録
  385.     * ファイルの最後-1に移動する
  386.     move.w    #SEEK_END,-(sp)
  387.     move.l    #-1,-(sp)    * offset=-1
  388.     move.w    fp,-(sp)
  389.     DOS    _SEEK
  390.     DOS    _FGETC        * 最後の1文字を読む(fpはすでに積まれている)
  391.     cmp.b    #EOF,d0        * $1aがある?
  392.     bne    @f        * ない=このまま追記
  393.     * EOFを消すためもう一度ファイルの最後に移動する(引数はすでにスタック上にある)
  394.     DOS    _SEEK
  395. @@:    addq.w    #8,sp
  396.     bra    10f
  397. *
  398. create:    * OPEN出来ない~新規ファイルかも知れない
  399.     move.w    #FA_ARCH,-(sp)
  400.     pea    OutFile(pc)
  401.     DOS    _CREATE
  402.     addq.w    #6,sp
  403.     tst.l    d0
  404.     bmi    err        * CREATEも出来ない=エラー
  405.     move.w    d0,fp        * fp記録
  406.     *
  407. 10:    moveq.l    #0,d1        * x=0(h.w),y=0(l.w)から
  408.     *
  409. 12:    GMDAPI0    GMD_Read1    * 1文字読み込み
  410.     swap    d0        * d0.h.w->d0.l.w=文字幅
  411.     swap    d1        * d1.l.w=x
  412.     add.w    d0,d1        * カーソル移動(x+=文字幅)
  413.     swap    d0        * d0.l.w=文字
  414.     * 書き出し
  415.     cmp.w    #NOCHR,d0
  416.     bne    @f
  417.     move.w    #SPC,d0        * 読み取れない文字はスペース化
  418. @@:    bsr    FileWT        * ファイル書きだし(d0.w)
  419.     *
  420.     cmp.w    d5,d1        * 1行分終了?(d5.l.w=CSRXMAX)
  421.     bhi    @f        * Yes(>wx-1)
  422.     * 1行内
  423.     swap    d1
  424.     bra    12b
  425.     *
  426. @@:    * 1行終了
  427.     move.w    #$0d0a,d0    * 改行を出力(CR+LF)
  428.     bsr    FileWT
  429.     *
  430.     clr.w    d1        * x=0
  431.     swap    d1        * x->d1.h.w
  432.     addq.w    #1,d1        * y+1
  433.     cmp.w    CSRYMAX,d1    * 全行終了?
  434.     bls    12b        * No(<=wy-1)
  435.     *
  436.     move.w    fp,-(sp)    * ファイルを閉じる
  437.     DOS    _CLOSE
  438.     addq.w    #2,sp
  439.     BEEP            * 終了の合図
  440.     bra    LT_CR        * カーソル戻してGMojiを即終了する
  441. *
  442. *
  443. FileWT:    * ファイル書き込みルーチン
  444. * d0.l,d2.w破壊
  445.     move.w    d0,d2        * push d0
  446.     cmp.w    #255,d2
  447.     bls    1f        * 1バイト文字
  448.     * 2バイト文字である
  449.     * 分割して出力
  450.     move.w    d0,-(sp)
  451.     move.b    (sp)+,d0    * d0.l.h.b -> d0.l.l.b
  452.     bsr    1f        * 上位バイト出力
  453.     move.b    d2,d0        * 下位バイト出力
  454. 1:    move.w    fp,-(sp)
  455.     move.w    d0,-(sp)
  456.     DOS    _FPUTC
  457.     addq.w    #4,sp
  458. *    moveq.l    #0,d0        * ok
  459.     rts
  460. *
  461. * 1行分メモリー上に取り込んで一気に書き出した方が良いような気もするが、
  462. * ワークがもったいないので今回はパス。ワークはテキスト1行最大128文字
  463. * なので、それが全部1/2,1/4角文字の場合を想定して128*2バイト必要である。
  464. *
  465. *------------------------------------
  466. * カーソル移動
  467. * d6.l = CSRY|CSRX
  468. * d5.l = CSRYMAX|CSRXMAX
  469.  
  470. LT_ESC:    * 終了
  471.     * キーボードバッファーをクリアして終了
  472.     KSDAPI0    KSD_Clear
  473. LT_CR:    * 終了
  474.     moveq.l    #-1,d7
  475. LT_UNDO:* カーソルを元の位置に戻す
  476.     move.l    xy0(pc),d6    * x|y
  477.     swap    d6        * y|x(他に合わせるため)
  478.     rts
  479.  
  480. LT_HOME:    * カーソルホーム
  481.     moveq.l    #0,d6        * x=y=0
  482.     rts
  483.  
  484. LT_DEL:        * カーソルエンド
  485.     move.l    d5,d6        * x=xm,y=ym
  486.     rts
  487.  
  488. LT_LEFT:
  489.     and.w    #SKctrl,d0
  490.     beq    @f        * LEFTのみ
  491.     * CTRL+LEFT : 左端
  492.     clr.w    d6        * x=0
  493.     rts
  494. *
  495. @@:    subq.w    #1,d6        * x--
  496.     bge    2f        * >=0 -> ret
  497.     move.w    d5,d6        * 画面左端x=0->右端x=xm & y-1
  498. LT_UP:
  499.     swap    d6        * y
  500.     subq.w    #1,d6        * y--
  501.     bge    @f        * >=0 -> ret
  502.     swap    d5        * ym
  503.     move.w    d5,d6        * 画面最上y=0->最下y=ym
  504. *    swap    d5
  505. @@:    swap    d6
  506. 2:    rts
  507.  
  508. LT_RIGHT:
  509.     move.w    d0,d1
  510.     and.w    #SKsft,d0
  511.     bne    LT_TAB        * SHIFT+→=TAB
  512.     and.w    #SKctrl,d1
  513.     beq    @f        * CTRLなし
  514.     * CTRL-RIGHT : 右端
  515.     move.w    d5,d6        * x=xm
  516.     rts
  517. *
  518. LT_TAB:
  519.     and.w    #SKopt1,d0
  520.     bne    LT_CR        * Opt.1+TAB -> 終了
  521.     and.w    #$fff8,d6    * $fff8=(d6.w/8)*8
  522.     addq.w    #8,d6
  523. @@:    * RIGHTのみ
  524.     addq.w    #1,d6        * x++
  525.     cmp.w    d5,d6        * x<=xm?
  526.     bls    3f        * yes -> ret
  527.     clr.w    d6        * 画面右端x=xm->左端x=0 & y+1
  528. LT_DOWN:
  529.     swap    d6        * y
  530.     swap    d5        * ym
  531.     addq.w    #1,d6        * y++
  532.     cmp.w    d5,d6        * y<=ym?
  533.     bls    @f        * yes -> ret
  534.     clr.w    d6        * 画面最下y=ym->最上y=0
  535. @@:    swap    d6
  536. *    swap    d5
  537. 3:    rts
  538.  
  539. *********************************************************************
  540.  
  541. Writer:
  542. * 1文字書き込みルーチン -> KSD
  543. * 主にGMDから呼び出される
  544.     move.w    4+2(sp),d1    * cc=文字コード
  545. Writer0:
  546.     cmp.w    #$ff,d1        * cc>$ff?
  547.     bls    @f        * no
  548.     * 2byte code
  549.     tst.b    mode        * 普通モード?
  550.     beq    2f        * Yes
  551.     * 半角モード(ASKが無い時は来ない)
  552.     * 全角->半角:変換できないものは消す
  553.     bsr    kacnv        * d1.w -> d1.w (d0/d2/a0破壊)
  554.     tst.w    d1        * 変換不可?
  555.     beq    3f        * Yes -> 変換不可は消す
  556.     * 実は変換結果が2バイトのこともある(濁点処理)ので2バイト書き込みする
  557.     * $00xxの時は00は書き込んでもKSDで消されるので問題なし
  558. 2:    move.b    d1,d2        * 保存
  559.     lsr.w    #8,d1
  560.     KSDAPI0    KSD_Write1    * d1.b -> KSD
  561.     tst.l    d0
  562.     bne    1f        * ok
  563.     move.b    d2,d1        * 復帰
  564. @@:    KSDAPI0    KSD_Write1    * d1.b -> KSD
  565.     tst.l    d0
  566.     beq    3f        * ok
  567. 1:    * Yes : これ以上は書き込めない(KSD Full)
  568.     BEEP            * d0,d1破壊
  569.     moveq.l    #1,d0        * return(1)
  570. 3:    rts
  571.  
  572. *********************************************************************
  573.  
  574. kacnv:
  575. * 全角->半角変換
  576. * d1.w <- 全角文字
  577. * -> d1.w ($??xx:半角文字) , $0000=変換不可
  578. * d0,a0破壊
  579.     lea    work(pc),a0
  580.     move.w    d1,(a0)
  581.     clr.b    2(a0)        * 0,1=文字 , 2=EOS
  582.     *
  583.     pea    (a0)
  584.     pea    (a0)        * 絶対に同じか短くなるので上書きする
  585.     pea    14.w        * 全角→半角文字列変換
  586.     DOS    _KNJCTRL
  587.     lea    12(sp),sp
  588.     *
  589.     move.b    1(a0),d0
  590.     beq    @f        * ??00 = 半角化された
  591.     * 半角化しても2文字になることがあるのでチェック
  592.     cmp.b    #'゙',d0        * 濁点
  593.     beq    1f
  594.     cmp.b    #'゚',d0        * 半濁点
  595.     beq    1f
  596.     * 変換不可 : 全角のまま
  597.     moveq.l    #0,d1
  598.     rts
  599.  
  600. @@:    * 半角1文字
  601.     moveq.l    #0,d1        * for .b = .w
  602.     move.b    (a0),d1
  603.     rts
  604.  
  605. 1:    * 仮名1文字+(半)濁点
  606.     move.w    (a0),d1
  607.     rts
  608.  
  609. *********************************************************************
  610. * ワーク2
  611. *********************************************************************
  612. * ここに置くワークは、常駐後に使われるもの
  613. * これらのワークエリアは常駐後に利用可能になるので、
  614. * 以下の非常駐ルーチンからは参照しないこと
  615. *------------------------------------------------------------------------------
  616. * オフセットテーブルの定義
  617.     .offset    0
  618. *---------------------------------------
  619.  
  620. _fp        .ds.w    1    * ファイルポインタ
  621. _xy0        .ds.l    1    * 最初のカーソル位置
  622. _Wt        .ds.l    1    * GMD 元Writer
  623. _Gp        .ds.l    1    * GMD 元Group
  624. _msc        .ds.w    1    * マウスカーソル表示モード
  625. _tm0        .ds.l    1    * 初期時間
  626. _txarg        .ds.w    6    * TXBOX引数
  627. _curptrn    .ds.w    16    * カーソル形状
  628. _brksts        .ds.w    1    * BREAK状態
  629.     .even
  630. _work        .ds.b    2+1    * 全角->半角文字変換ワーク(2+EOS+even)
  631. _fask        .ds.b    1    * ASK存在フラグ($00=あり,!=なし)
  632.     .even
  633. _KEEP_END:        * 常駐部分最後
  634.  
  635. *------------------------------------------------------------------------------
  636. * 実際のワークエリアの定義
  637. *------------------------------------------------------------------------------
  638.  
  639.     .text    * .offset解除
  640. work2:
  641.  
  642. fp        equ    work2+_fp
  643. xy0        equ    work2+_xy0
  644. Wt        equ    work2+_Wt
  645. Gp        equ    work2+_Gp
  646. msc        equ    work2+_msc
  647. tm0        equ    work2+_tm0
  648. txarg        equ    work2+_txarg
  649. curptrn        equ    work2+_curptrn
  650. brksts        equ    work2+_brksts
  651. work        equ    work2+_work
  652. fask        equ    work2+_fask
  653.  
  654. * 常駐部分最後
  655. KEEP_END    equ    work2+_KEEP_END
  656.  
  657. *********************************************************************
  658. *    非常駐ルーチン
  659. *********************************************************************
  660. * この中ではa0は壊さないこと(プロセス管理ポインタを参照するため)
  661.  
  662.     .even
  663. chkarg:    * コマンドライン解析(a2=コマンドライン)
  664.     tst.b    (a2)+        * コマンドラインサイズ = 0?
  665.     beq    eos        * Yes : 引数がない
  666. arglp:    bsr    skipsp        * 空白飛ばし
  667.     tst.b    d0        * end?
  668.     beq    eos        * Yes
  669.     * オプションは -? or /?
  670.     cmp.b    #'-',d0
  671.     beq    chkopt
  672.     cmp.b    #'/',d0
  673.     bne    arglp
  674. chkopt:    * オプションチェック
  675.     addq.w    #1,a2        * skip '-' or '/'
  676.     move.b    (a2)+,d0
  677.     beq    usage        * -/のみでオプションがない
  678.     or.b    #$20,d0        * 小文字化
  679.     lea    flags-2(pc),a6    * 後で+2するため-2しておく
  680. @@:    addq.w    #2,a6
  681.     tst.b    1(a6)
  682.     beq    usage        * 全オプションチェック終わり -> 規定外オプション
  683.     tst.b    (a6)        * すでにフラグがセットされている?
  684.     bne    @b        * Yes : 飛ばす(2重指定だからbne usageにしてもいい)
  685.     cmp.b    1(a6),d0    * オプションチェック
  686.     bne    @b        * 不一致
  687.     st.b    (a6)        * セット
  688.     bra    arglp        * コマンドライン処理へ戻る
  689.  
  690. skipsp:    * 空白飛ばし
  691.     move.b    (a2)+,d0
  692.     cmp.b    #' ',d0
  693.     beq    skipsp
  694.     cmp.b    #$09,d0        * TAB
  695.     beq    skipsp
  696.     subq.w    #1,a2        * a2が1つ進んでいるので戻す
  697. eos:    rts
  698.  
  699. *********************************************************************
  700. *    メイン
  701. *********************************************************************
  702.  
  703.     .xref    keepchk
  704.     .xref    _KSDSetAPI
  705.     .xref    KSDCallAPI
  706.     .xref    _GMDSetAPI
  707.     .xref    GMDCallAPI
  708.  
  709. main:
  710.     lea.l    initsp(pc),sp    * PROGRAM=の時のため
  711.     
  712.     pea    title(pc)    * タイトル表示
  713.     DOS    _PRINT
  714.     *
  715.     move.l    #(id-KEEP_START),-(sp)    * 識別子の相対位置
  716.     pea.l    (a0)        * 自分のメモリ管理ポインタ
  717.     bsr    keepchk        * 常駐チェック
  718.     lea    4*3(sp),sp
  719.     move.b    d0,d7        * d7 :0=常駐してない , -1=常駐している
  720.     
  721.     bsr    chkarg        * コマンドライン引数チェック
  722.     tst.b    rflag        * -r : 常駐解除?
  723.     beq    keep        * no
  724. *
  725. * 常駐解除
  726. *
  727.     tst.b    d7        * 常駐している?
  728.     beq    Err_NoKp    * No -> error
  729.     
  730.     * a0=常駐しているルーチンのメモリ管理ポインタ
  731.     pea.l    MPSIZ(a0)
  732.     DOS    _MFREE        * 自己プロセスメモリー解放
  733.     addq.w    #4,sp
  734.     tst.l    d0
  735.     bmi    Err_Kai        * なぜかメモリー解放出来ない時
  736.     
  737.     bsr    SetAPI        * API設定&アドレス保存
  738.     
  739.     * KSDの外部起動プログラムを解除する
  740.     lea    ExtFunc(pc),a2
  741.     KSDAPI    KSD_UnlinkEFunc
  742.     tst.l    d0
  743.     bne    Err_Kai        * その起動キーで起動されるプログラムが存在しない
  744.                 *(あり得ないけど)
  745.     
  746.     * KSD/GMDを常駐アンロックする
  747.     KSDAPI    KSD_JUnlock
  748.     GMDAPI    GMD_JUnlock
  749.     
  750.     * 常駐解除正常終了
  751.     pea.l    MesRelease(pc)
  752.     DOS    _PRINT
  753.     addq.w    #4,sp
  754.     clr.w    -(sp)        * exit(0)
  755.     DOS    _EXIT2
  756. *
  757. * 常駐
  758. *
  759. keep:
  760.     tst.b    d7        * 常駐している?
  761.     bne    Err_Dbl        * Yes -> error(2重常駐)
  762.     
  763.     * KSD/GMDを常駐ロックする
  764.     bsr    SetAPI        * API設定&アドレス保存
  765.     KSDAPI    KSD_JLock
  766.     GMDAPI    GMD_JLock
  767.     
  768.     * KSDの外部起動プログラムとして登録する
  769.     lea    ExtFunc(pc),a2
  770.     KSDAPI    KSD_LinkEFunc
  771.     tst.l    d0
  772.     bne    Err_UseKey    * 起動キーがすでに使われている
  773.     *
  774.     * 組み込みOK
  775.     pea    MesKeep(pc)
  776.     DOS    _PRINT
  777.     clr.w    -(sp)        * exit(0)相当
  778.     pea    (KEEP_END-KEEP_START).w
  779.     DOS    _KEEPPR
  780. *
  781. *
  782. SetAPI:    * API設定&アドレス保存
  783.     * すでに常駐している状態でこの処理を走らせてはいけない(それがV1.2迄のバグ)
  784.     * KSD check
  785.     movem.l    a0/a2,-(sp)
  786.     jsr    _KSDSetAPI
  787.     movem.l    (sp)+,a0/a2
  788.     tst.l    d0
  789.     beq    Err_NoKSD
  790.     move.l    d0,AdKSDAPI
  791.     * GMD check
  792.     movem.l    a0/a2,-(sp)
  793.     jsr    _GMDSetAPI
  794.     movem.l    (sp)+,a0/a2
  795.     tst.l    d0
  796.     beq    Err_NoGMD
  797.     move.l    d0,AdGMDAPI
  798.     rts
  799. *
  800. * エラー終了
  801. *
  802. Err_UseKey:    * 起動キーがすでに使われている
  803.     KSDAPI    KSD_JUnlock    * KSDとGMDがロックされているので解除
  804.     GMDAPI    GMD_JUnlock
  805.     lea.l    ErrUseKey(pc),a0
  806.     bra.s    error
  807. Err_NoKSD:    * KSDがない
  808.     lea.l    ErrNoKSD(pc),a0
  809.     bra.s    error
  810. Err_NoGMD:    * GMDがない
  811.     lea.l    ErrNoGMD(pc),a0
  812.     bra.s    error
  813. Err_NoKp:    * 常駐していないのに解除しようとした
  814.     lea.l    NoKeep(pc),a0
  815.     bra.s    error
  816. Err_Dbl:    * 2重常駐
  817.     lea.l    AlreadyKeep(pc),a0
  818.     bra.s    error
  819. Err_Kai:    * 常駐解除不可
  820.     lea.l    CantRelease(pc),a0
  821.     bra.s    error
  822. usage:    * 使用法
  823.     lea.l    MesUsage(pc),a0
  824. error:    move.w    #2,-(sp)    * STDERR
  825.     pea.l    (a0)
  826.     DOS    _FPUTS        * 表示
  827.     addq.w    #2+4,sp
  828.     move.w    #2,-(sp)    * exit(2)
  829.     DOS    _EXIT2
  830.  
  831. ******************************************************************************
  832. * メッセージなど
  833. ******************************************************************************
  834.  
  835.     .even
  836. title:        .dc.b    'GMoji V1.4 Copyright 1997-98,2000 by AIG-Soft'
  837. *        .dc.b    $0d,$0a,$09,'Debug中 001'    * CrLfにつながる
  838. CrLf        .dc.b    $0d,$0a,0
  839. MesKeep:    .dc.b    '常駐しました',$0d,$0a,0
  840. MesRelease:    .dc.b    '常駐解除しました',$0d,$0a,0
  841. NoKeep:        .dc.b    '常駐していません',$0d,$0a,0
  842. AlreadyKeep:    .dc.b    'すでに常駐しています',$0d,$0a,0
  843. CantRelease:    .dc.b    '常駐解除できません',$0d,$0a,0
  844. ErrNoKSD    .dc.b    'KSDが組み込まれていません',$0d,$0a,0
  845. ErrNoGMD    .dc.b    'GMDが組み込まれていません',$0d,$0a,0
  846. ErrUseKey    .dc.b    '起動キー[Opt.1+TAB]が他のプログラムで使われています',$0d,$0a,0
  847.  
  848. MesUsage:    .dc.b    'GMoji [/R]',$0d,$0a,0
  849.  
  850.     .even
  851. flags:        * work,フラグキャラクター
  852. rflag        .dc.b    0,'r'    * 常駐解除フラグ
  853.         .dc.b    0,0    * end of table
  854.  
  855. ******************************************************************************
  856. * 非常駐ルーチンが使うスタック
  857. ******************************************************************************
  858.     .stack
  859.     .even
  860.     .ds.l    512
  861. initsp:
  862. ******************************************************************************
  863.     .end    main
  864.